// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// Copyright (C) 2012-2013	JoostinOnline

/*
init.h

Startup and shutdown functions
*/

#include <fat.h>
#include <ogc/es.h>
#include <ogc/isfs.h>
#include <ogc/machine/processor.h>
#include <runtimeiospatch/runtimeiospatch.h>
#include <sdcard/wiisd_io.h>
#include <stdarg.h>
#include <stdlib.h>

#include "cfg.h"
#include "debug.h"
#include "fsop.h"
#include "grlib/grlib.h"
#include "init.h"
#include "io.h"
#include "postLoader.h"
#include "sysconf.h"

#include "background_png.h"
#include "font_ttf.h"
#include "wiicursor_png.h"

GRRLIB_texImg *bkg;
GRRLIB_texImg *cursor;
GRRLIB_ttfFont *myFont;

s_present present;

int Initialize(void) {
	fatInitDefault();
	DebugStart(true, "sd:/segui.log");
	Debug("-[SE GUI Debug]----------------------------------------");

	// Apply standard Wii patches for file permissions on vWii
	s32 PatchCount = IosPatch_RUNTIME(true, false, false, false);
	(void) PatchCount; //This just shuts up the warning about it being unused when debug logging is disabled
	Debug("%i IOS patches applied", PatchCount);
	IosPatch_RUNTIME(true, false, false, false);

	grlib_Init();
	Debug("grlib initialized");

	__ES_Init();
	Debug("ES initialized");

	ISFS_Initialize();
	Debug("ISFS initialized");

	SYSCONF_Init();
	Debug("SYSCONF initialized");

	bkg = GRRLIB_LoadTexturePNG(background_png); // Background image
	cursor = GRRLIB_LoadTexturePNG(wiicursor_png); // Cursor/pointer
	myFont = GRRLIB_LoadTTF(font_ttf, font_ttf_size); // Truetype font

	grlibSettings.fontMode = GRLIB_FONTMODE_TTF;
	cursor->offsetx = 10;
	cursor->offsety = 3;

	ScanTheme();

	// Initiate awesomeness!
	int i; // Opacity
	for (i=0; i<255; i = i + 2) // Fade background image in from black screen
	{
		GRRLIB_DrawImg(0, 0, bkg, 0, 1, 1, RGBA(255, 255, 255, i)); // Opacity increases as i does
		grlib_Render();
	}
	grlib_SetWiimotePointer(cursor, 0); // Set the cursor to start in the top left corner
	Debug("------------------------------------------");
	return 1;
} // Initialize

bool LoadPresentCfg(char *path) {
	s_cfg *cfg = cfg_Alloc(path, 0);
	if (cfg) {
		cfg_GetInt(cfg, "resolution", &present.resolution);
		cfg_GetInt(cfg, "widescreen", &present.widescreen);;
		cfg_GetInt(cfg, "sensorbar", &present.sensorbar);
		cfg_GetInt(cfg, "soundmode", &present.soundmode);
		cfg_GetInt(cfg, "rumble", &present.rumble);
		cfg_GetInt(cfg, "burnin", &present.burnin);
		cfg_GetInt(cfg, "shutdown", &present.shutdown);
		cfg_GetInt(cfg, "sensitivity", &present.sensitivity);
		cfg_GetInt(cfg, "wc24", &present.wc24);
		cfg_GetInt(cfg, "auto_exit", &present.auto_exit);
		cfg_GetString(cfg, "exit_to", present.exit_to);
		cfg_Free(cfg);
		return true;
	}
	return false;
}

int LoadFont(char *path) {
	unsigned char *fontfile;
	u32 filesize = 0;

	if (fsop_FileExist (path)) filesize = GRRLIB_LoadFile(path, &fontfile);
	if (filesize > 0)
		{
			if (myFont != NULL) GRRLIB_FreeTTF(myFont);
			myFont = GRRLIB_LoadTTF(fontfile, filesize);
			return 1;
		}
	return 0;
} // LoadFont


int LoadTheme(int dev) {
	char mnt[4] = {0};
	char path[40] = {0};
	char themeloc[32] = {0};
	if (dev == DEV_SD) strcpy(mnt, "sd");
	if (dev == DEV_USB) strcpy(mnt, "usb");

	// mnt will still be needed for the background and present.cfg
	strcpy(themeloc, mnt);

	sprintf(path, "%s://ploader/present.cfg", mnt);
	present.enabled = LoadPresentCfg(path);

	sprintf (path, "%s://ploader/SE_theme/theme.cfg", themeloc);
	if ((fsop_FileExist (path)) && (!pl_IsDirectBackAvail()))
	{
	// Use Settings Editor theme if available, and if directBackToPl is 0
		strcat(themeloc, "://ploader/SE_theme/");
	} else {
	// Use postLoader theme otherwise
		strcat(themeloc, "://ploader/theme/");
	// If there is no postLoader theme, then it will use the built in theme
	}

	// Default background png
	sprintf (path, "%s://ploader/SettingsEditor.png", mnt);
	if (fsop_FileExist(path))
		{
			if (bkg != NULL) GRRLIB_FreeTexture (bkg);
			bkg = GRRLIB_LoadTextureFromFile (path);
		} else {
		// If a default background doesn't exist, try the bkg.png file
			sprintf(path, "%sbkg.png", themeloc);
			if (fsop_FileExist(path))
			{
				if (bkg != NULL) GRRLIB_FreeTexture (bkg);
				bkg = GRRLIB_LoadTextureFromFile(path);
			}
		}


	// Load custom font if it exists
	sprintf(path, "%sfont.ttf", themeloc);
	grlibSettings.theme.customfont = LoadFont(path);

	sprintf (path, "%sbutton.png", themeloc);
	grlibSettings.theme.texButton = GRRLIB_LoadTextureFromFile (path);

	sprintf(path, "%sbutton_sel.png", themeloc);
	grlibSettings.theme.texButtonSel = GRRLIB_LoadTextureFromFile (path);

	sprintf(path, "%swindow.png", themeloc);
	grlibSettings.theme.texWindow = GRRLIB_LoadTextureFromFile (path);

	sprintf(path, "%swindowbk.png", themeloc);
	grlibSettings.theme.texWindowBk = GRRLIB_LoadTextureFromFile (path);

	sprintf(path, "%stheme.cfg", themeloc);
	s_cfg *cfg = cfg_Alloc(path, 0);
	if (cfg)
		{
		cfg_GetInt(cfg, "grlibSettings.theme.windowMagX", &grlibSettings.theme.windowMagX);
		cfg_GetInt(cfg, "grlibSettings.theme.windowMagY", &grlibSettings.theme.windowMagY);
		cfg_GetInt(cfg, "grlibSettings.theme.buttonMagX", &grlibSettings.theme.buttonMagX);
		cfg_GetInt(cfg, "grlibSettings.theme.buttonMagY", &grlibSettings.theme.buttonMagY);

		cfg_GetInt(cfg, "grlibSettings.theme.buttonsTextOffsetY", &grlibSettings.theme.buttonsTextOffsetY);
		cfg_GetInt(cfg, "grlibSettings.fontBMF_reverse", &grlibSettings.fontReverse);

		grlibSettings.theme.enabled = true;

		cfg_Free(cfg);
		}

	return 0;
} // LoadTheme

void ScanTheme(void)
	{
	if (Fat_Mount(DEV_SD, 1))
		LoadTheme(DEV_SD);

	if (!grlibSettings.theme.enabled)
		{
		if (Fat_Mount(DEV_USB, 1))
			LoadTheme(DEV_USB);
		}

	Fat_Unmount();
} // ScanTheme


void fadeOut(void) {
	int i; // Opacity
	for (i=255; i>0; i=i-7) // Fade background image out to black screen
		{
		GRRLIB_DrawImg(0, 0, bkg, 0, 1, 1, RGBA(255, 255, 255, i)); // Opacity decreases as i does
		grlib_Render();
		}
} // fadeOut


bool CheckIfNeek(void) {
	u32 num = 0;
	return !(ISFS_ReadDir("/Sneek", NULL, &num));
} // CheckIfNeek

bool CheckIfNeek2(void) {
	// This will still work even if crediar (or someone else)
	// changes the Sneek folder to something else.
	// Thanks to tueidj for this code.
	u32 ownerID;
	u16 groupID;
	u8  attributes, ownerperm, groupperm, otherperm;
	ISFS_GetAttr("/shared1/00000000.app", &ownerID, &groupID, &attributes, &ownerperm, &groupperm, &otherperm);
	return otherperm;
} // CheckIfNeek2


int Deinit (void) {
	Debug("------------------------------------------");
	Debug("Deinitiatizing...");

	fadeOut(); // Fade out in an orgy of awesomeness

	ISFS_Deinitialize();
	Debug("ISFS Denitialized");

	grlib_Exit();
	Debug("grlib Denitialized");

	Debug("Stopping Debug");
	DebugStop();
	gprintf("Debug stopped\n");

	return 1;
} // Deinit